package awk.lock;

import awk.thread.ThreadPoolUtils;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @description:
 * @author: wanghaifeng
 * @date: 2021/3/5
 * 死锁的出发方式有很多种:
 * 1.不释放锁(或者释放锁失败等)
 * 2.锁互相依赖
 * 这里举例2
 */
public class DeadLock {

    static DeadLock lockA = new DeadLock();
    static DeadLock lockB = new DeadLock();
    int value = 0;
    int another = 0;

    public static void main(String[] args) {
        ThreadPoolExecutor pool = ThreadPoolUtils.getPool();
        //线程1和线程2如果分别执行add()和dec()方法 产生死锁
        pool.execute(() -> {
            lockA.add(3);
        });

        pool.execute(() -> {
            lockB.dec(2);
        });
    }

    /**
     * 方法作用:
     * 先增加 lockA 的
     *
     * @param m
     */
    public void add(int m) {
        synchronized (lockA) {
            this.value += m;
            synchronized (lockB) {
                this.another += m;
            }
        }
    }

    public void dec(int m) {
        synchronized (lockB) { //解决死锁:看add方法,线程获取锁的顺序要一致,这里先获取 lockA
            this.another -= m;
            synchronized (lockA) {
                this.value -= m;
            }
        }
    }
}
